package com.ayf.payment.game.api.channel.zhuofutong;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.BaseHandler;
import com.ayf.payment.game.api.channel.zhuofutong.util.HttpTookit;
import com.ayf.payment.game.api.channel.zhuofutong.util.SignUtils;
import com.ayf.payment.game.api.dto.platform.SubstitutePayConfigDTO;
import com.ayf.payment.game.api.dto.platform.pay.WanXiangPayConfigParamVO;
import com.ayf.payment.game.api.service.platform.SubstitutePayConfigService;
import com.ayf.payment.game.api.type.MerchantPayOrderStatusEnum;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wwl
 * @description:
 * @date 2021/2/22 13:50
 */
@Component
public class ZhuoFuTongPayHandler implements BaseHandler {

    @Autowired
    private SubstitutePayConfigService substitutePayConfigService;

    @Override
    public JSONObject orderCreate(JSONObject inputParam) {
        JSONObject resJson = new JSONObject();
        String merchantOrderNo = inputParam.getString("merchant_order_no");
        resJson.put("merchantOrderNo", merchantOrderNo);
        resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());

        String traceId = inputParam.getString("traceId");
        String amount = inputParam.getString("amount");
        String username = inputParam.getString("account_name");
        String bankName = inputParam.getString("bank_name");
        String banktype = getBankType(traceId, bankName);
        String bankno = inputParam.getString("account_no");

        Integer substitutePayConfigId = inputParam.getInteger("substitutePayConfigId");
        SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(substitutePayConfigId);
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();

        String website = wanXiangPayConfigParamVO.getWebsite();
        String parter = wanXiangPayConfigParamVO.getParter();
        String notifyUrl = wanXiangPayConfigParamVO.getNotifyurl();
        String key = wanXiangPayConfigParamVO.getKey();

        if (!website.endsWith("/")){
            website=website.concat("/");
        }
        website=website.concat("api/pay");
        if (!notifyUrl.endsWith("/")){
            notifyUrl=notifyUrl.concat("/");
        }

        Map<String, String> parMap = new HashMap<>();
        parMap.put("mchId", parter);
        parMap.put("mchRequestId", merchantOrderNo);
        parMap.put("amount", amount);
        parMap.put("mchNotifyUrl",notifyUrl.concat("gameapip/v/zftong/pay/paynotify"));
        parMap.put("name", username);
        parMap.put("bankCardNum", bankno);
        parMap.put("bankCode", banktype);
        parMap.put("serviceName", "com.zhuofutong.api.transferDomestic");
        parMap.put("signType", "MD5");
        String sign = SignUtils.sign(parMap,key);
        parMap.put("sign", sign);
        try {
            String param = JSON.toJSONString(parMap);
            LogPortal.info("{} 卓付通代付下单 商户订单号:{} 请求报文:{}", traceId,merchantOrderNo,param);
            String dataStr = HttpTookit.HttpPostWithJson(website, param);
            LogPortal.info("{} 卓付通代付下单 商户订单号:{} 响应报文:{}", traceId, merchantOrderNo, dataStr);
            JSONObject jsonData = JSONObject.parseObject(dataStr);
            String code = jsonData.getString("code"); //返回code
            String requestId = jsonData.getString("requestId"); //返回 通道订单号
            if ("0".equals(code)) {
                resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());
                resJson.put("channelOrderNo", requestId);
            } else {
                String msg = jsonData.getString("msg");
                if (StringUtils.isEmpty(msg)){
                    msg = "代付失败";
                }
                resJson.put("status", MerchantPayOrderStatusEnum.PAY_FAIL.getStatus());
                resJson.put("failReason",msg);
            }
        } catch (Throwable e) {
            if (e instanceof SocketTimeoutException){
                LogPortal.error("{} 卓付通代付下单失败 商户订单号:{} 发生SocketTimeoutException异常", traceId,merchantOrderNo);
            } else {
                LogPortal.error("{} 卓付通代付下单失败 商户订单号:{} 发生{}异常",e,traceId, e.getClass().getName(), merchantOrderNo);
                resJson.put("status", MerchantPayOrderStatusEnum.PAY_FAIL.getStatus());
                resJson.put("failReason", "系统繁忙，请稍后重试");
                return resJson;
            }
        }
        LogPortal.info("{} 卓付通代付下单 商户订单号:{} 响应报文:{}", traceId, merchantOrderNo, resJson.toJSONString());
        return resJson;
    }

    @Override
    public JSONObject orderQuery(JSONObject inputParam) {
        JSONObject resJson = new JSONObject();
        String merchantOrderNo = inputParam.getString("merchant_order_no");
        resJson.put("merchantOrderNo", merchantOrderNo);
        resJson.put("status", MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus());

        String traceId = inputParam.getString("traceId");

        Integer substitutePayConfigId = inputParam.getInteger("substitutePayConfigId");
        SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(substitutePayConfigId);
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();

//        WanXiangPayConfigParamVO wanXiangPayConfigParamVO =getTestWanXiangPayConfigParamVO();
        String website = wanXiangPayConfigParamVO.getWebsite();
        String parter = wanXiangPayConfigParamVO.getParter();
        String key = wanXiangPayConfigParamVO.getKey();
        if (!website.endsWith("/")){
            website=website.concat("/");
        }
        website=website.concat("api/pay");

        Map<String, String> parMap = new HashMap<>();
        parMap.put("mchRequestId",merchantOrderNo);
        parMap.put("serviceName", "com.zhuofutong.api.transferDomestic.query");
        parMap.put("mchId", parter);
        parMap.put("signType", "MD5");
        String sign = SignUtils.sign(parMap,key);
        parMap.put("sign", sign);
        String parameter = JSON.toJSONString(parMap);
        try {
            LogPortal.info("{} 卓付通代付订单查询 订单号:{} 请求参数:{}", traceId, merchantOrderNo,parameter);
            String s = HttpTookit.HttpPostWithJson(website, parameter);
            LogPortal.info("{} 卓付通代付订单查询 订单号:{} 请求返回数据:{}",traceId,merchantOrderNo,s);
            JSONObject jsonDate = JSONObject.parseObject(s);
            String code = jsonDate.getString("code");
            String status = jsonDate.getString("status");
            if ("0".equals(code)) { // 业务处理成功
                String signReturn = jsonDate.getString("sign");
                Map<String, String> pardicMap = new HashMap<String, String>();
                pardicMap.put("requestId",jsonDate.getString("requestId"));
                pardicMap.put("status",status);
                String signStr = SignUtils.sign(pardicMap,key).toUpperCase();
                if (signStr.equals(signReturn)) {
                    if ("SUCCESS".equals(status)){
                        resJson.put("status", MerchantPayOrderStatusEnum.PAY_SUCCESS.getStatus());
                    } else if ("FAILED".equals(status) || "CANCEL".equals(status)){
                        resJson.put("status", MerchantPayOrderStatusEnum.PAY_FAIL.getStatus());
                    }
                } else {
                    LogPortal.error("{} 卓付通代付订单查询失败  订单号:{} 支付通道返回签名验签失败,通道签名[{}],系统签名[{}]",traceId,merchantOrderNo,signReturn,signStr);
                }
            } else {
                LogPortal.error("{} 卓付通代付订单查询失败 订单号:{} 支付通道返回:{}",traceId,merchantOrderNo,jsonDate.getString("msg"));
            }
        } catch (Exception e) {
            LogPortal.error("{} 卓付通代付订单查询失败 订单号:{} 发生{}异常",e,traceId,merchantOrderNo,e.getClass().getName());
        }
        LogPortal.info("{} 卓付通代付订单查询 订单号:{} 响应报文[{}]", traceId,merchantOrderNo,resJson.toJSONString());
        return resJson;
    }

    private String getBankType(String traceId, String bankName) {
        if (bankName.contains("农业银行")) {
            return "ABC";
        } else if (bankName.contains("中国银行")) {
            return "BOC";
        } else if (bankName.contains("建设银行")) {
            return "CCB";
        } else if (bankName.contains("交通银行")) {
            return "BOCO";
        } else if (bankName.contains("招商银行")) {
            return "CMBCHINA";
        } else if (bankName.contains("广东发展银行")) {
            return "GDB";
        } else if (bankName.contains("广发银行")) {
            return "GDB";
        }else if (bankName.contains("中信银行")) {
            return "ECITIC";
        } else if (bankName.contains("民生银行")) {
            return "CMBC";
        } else if (bankName.contains("光大银行")) {
            return "CEB";
        } else if (bankName.contains("平安银行")) {
            return "SZPA";
        } else if (bankName.contains("邮政储蓄")) {
            return "PSBC";
        } else if (bankName.contains("兴业银行")) {
            return "CIB";
        }else if (bankName.contains("工商银行")) {
            return "ICBC";
        }else if (bankName.contains("杭州银行")) {
            return "HZBANK";
        }else if (bankName.contains("宁波银行")) {
            return "NBCB";
        } else {
            LogPortal.error("{} 卓付通代付银行名称[{}]不支持",traceId, bankName);
            return null;
        }
    }
    @Override
    public JSONObject balanceQuery(JSONObject inputParam) {
        JSONObject resJson = new JSONObject();
        String traceId = inputParam.getString("traceId");
        String bankName = inputParam.getString("bankName");
        String bankType = getBankType(traceId, bankName);
        if (StringUtils.isEmpty(bankType)) {
            resJson.put("status", "2");
            return resJson;
        }
        Integer substitutePayConfigId = inputParam.getInteger("substitutePayConfigId");
        SubstitutePayConfigDTO substitutePayConfigDTO = substitutePayConfigService.getSubstitutePayConfigById(substitutePayConfigId);
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = substitutePayConfigDTO.getWanXiangPayConfigParamVO();

        String website = wanXiangPayConfigParamVO.getWebsite();
        String parter = wanXiangPayConfigParamVO.getParter();
        String key = wanXiangPayConfigParamVO.getKey();

        if (!website.endsWith("/")){
            website=website.concat("/");
        }
        website=website.concat("api/pay");

        Map<String, String> parMap = new HashMap<>();
        parMap.put("serviceName", "com.zhuofutong.api.pay.balance");
        parMap.put("mchId", parter);
        parMap.put("signType", "MD5");
        String sign = SignUtils.sign(parMap,key);
        parMap.put("sign", sign);
        String parameter = JSON.toJSONString(parMap);
        try {
            LogPortal.info("{} 卓付通代付余额查询 请求参数:{}", traceId, parameter);
            String s = HttpTookit.HttpPostWithJson(website, parameter);
            LogPortal.info("{} 卓付通代付余额查询 返回报文:{}", traceId, s);
            JSONObject jsonDate = JSONObject.parseObject(s);
            String code = jsonDate.getString("code");
            if ("0".equals(code)) { // 业务处理成功
                String balance = jsonDate.getString("balance");
                String signReturn = jsonDate.getString("sign");
                String mchId = jsonDate.getString("mchId");
                Map<String, String> pardicMap = new HashMap<>();
                pardicMap.put("balance",balance);
                pardicMap.put("mchId",mchId);
                String signStr = SignUtils.sign(pardicMap,key).toUpperCase();
                if (signStr.equals(signReturn)) {
                    resJson.put("status", "1");
                    resJson.put("balance", balance);
                } else {
                    resJson.put("status", "0");
                    LogPortal.error("{} 卓付通代付余额查询失败-支付通道返回签名验签失败,通道签名[{}],系统签名[{}]",traceId,signReturn,signStr);
                }
            } else {
                resJson.put("status", "0");
                LogPortal.error("{} 卓付通代付余额查询失败-支付通道系统繁忙，请稍后重试", traceId);
            }
        } catch (Exception e) {
            resJson.put("status", "0");
            LogPortal.error("{} 卓付通代付余额查询失败,发生{}异常",e,traceId, e.getClass().getName());
        }
        LogPortal.info("{} 卓付通代付余额查询 响应报文[{}]", traceId,resJson.toJSONString());
        return resJson;
    }

    private static void testOrderQuery(){
        JSONObject inputParam = new JSONObject();
        inputParam.put("merchant_order_no","Y2021030194487019");
        inputParam.put("traceId", SnowFlakeUtils.getTraceId());
        ZhuoFuTongPayHandler zhuoFuTongPayHandler = new ZhuoFuTongPayHandler();
        zhuoFuTongPayHandler.orderQuery(inputParam);
    }

    /**
     * 构造测试请求通道商户参数
     * @return
     */
    private static WanXiangPayConfigParamVO getTestWanXiangPayConfigParamVO(){
        WanXiangPayConfigParamVO wanXiangPayConfigParamVO = new WanXiangPayConfigParamVO();
        wanXiangPayConfigParamVO.setWebsite("http://zf.zhihaowang888.com");
        wanXiangPayConfigParamVO.setParter("10050");
        wanXiangPayConfigParamVO.setKey("Z93G9WBWWEJ1U03YBQ9YWN8N509LUANG");
        wanXiangPayConfigParamVO.setNotifyurl("http://t1gameweb3.potiandao.cn");
        return wanXiangPayConfigParamVO;
    }

    public static void main(String[] args) {
        testOrderQuery();
    }
}
